<!--
 * @Description: 第七章 认识Reactive全家桶 reactive
 * @Author: IA ia@kepro.space
 * @Date: 2025-02-11 11:18:12
-->

<template>
  <div>
    <div>
      <p>Reactive</p>
      <div>
        <p>- 自动推导泛型</p>
        <p>{{ reactive_1 }}</p>
      </div>
      <div>
        <p>- 手动设置泛型</p>
        <p>{{ reactive_2 }}</p>
      </div>
      <div>
        <p>- 自定义泛型类型</p>
        <p>{{ reactive_3 }}</p>
      </div>
    </div>
    <hr />
    <div>
      <p>reactive 修改值不需要 .value</p>
      <form>
        <label>
          姓名
          <input v-model="reactive_form.name" type="text" />
        </label>
        <label>
          年龄
          <input v-model="reactive_form.age" type="text" />
        </label>
        <button @click.prevent="reactive_form_submit">reactive_form 提交</button>
        <p>{{ reactive_form_val }}</p>
      </form>
    </div>
    <hr />
    <div>
      <p>reactive 数组遍历</p>
      <div>
        <p>数组实时添加</p>
        <ul>
          <li v-for="(item, index) in reactive_list">{{ index }} {{ item }}</li>
        </ul>
        <button @click="reactive_list_add">reactive_list 添加</button>
      </div>
      <div>
        <p>数组异步添加-方案1</p>
        <ul>
          <li v-for="(item, index) in reactive_list_asyn_1">{{ index }} {{ item }}</li>
        </ul>
        <button @click="reactive_list_asyn_1_add">reactive_list_asyn1 添加</button>
      </div>
      <div>
        <p>数组异步添加-方案2</p>
        <ul>
          <li v-for="(item, index) in reactive_list_asyn_2.arr">{{ index }} {{ item }}</li>
        </ul>
        <button @click="reactive_list_asyn_2_add">reactive_list_asyn2 添加</button>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
// ref reactive 都是响应对象
// ref 支持所有类型
// reactive 源码泛型约束，只支持引用类型 Array Object Map Set
// ref 赋值需要添加 .value ， reactive 赋值不需要 .value
// reactive 是proxy代理的对象, 直接赋值会破坏响应对象，
// 对于数组，可以用push 加解构

// 自动推导泛型
let reactive_1 = reactive({
  name: 'I am reactive 1 : 自动推导泛型 .',
  age: 1000,
})

// 手动设置泛型
let reactive_2 = reactive<object>({
  name: 'I am reactive 2 : 手动设置泛型 .',
  age: 1000,
})

type reactive_3_type = {
  name: string
  age: number
}

// 自定义泛型类型
let reactive_3 = reactive<reactive_3_type>({
  name: 'I am reactive 3 : 自定义泛型类型 .',
  age: 1000,
})

let reactive_form = reactive({
  name: 'I am reactive form .',
  age: 1234,
})

let reactive_form_val = reactive([])

let reactive_form_submit = () => {
  reactive_form_val = reactive_form
  console.log('reactive_form: ', reactive_form)
  console.log('reactive_form_val: ', reactive_form_val)
}

let reactive_list = reactive<string[]>([])

let reactive_list_add = () => {
  reactive_list.push('DDD')
}

// reactive 直接赋值会破坏响应对象，解决方案1，可以用push 加解构
let reactive_list_asyn_1 = reactive<string[]>([])

let reactive_list_asyn_1_add = () => {
  setTimeout(() => {
    let res = ['AAA', 'BBB', 'CCC']
    // 直接赋值会破坏响应对象
    // reactive_list_asyn_1 = res
    // 要解构
    reactive_list_asyn_1.push(...res)
    reactive_list_asyn_1.push(Math.random())
    console.log('reactive_list_asyn_1: ', reactive_list_asyn_1)
  }, 2000)
}

// reactive 直接赋值会破坏响应对象，解决方案2，把数组作为一个属性
let reactive_list_asyn_2 = reactive<string[]>({
  arr: [],
})

let reactive_list_asyn_2_add = () => {
  setTimeout(() => {
    let res = ['EEE', 'FFF', 'GGG']
    // 直接赋值会破坏响应对象
    // reactive_list_asyn_1 = res
    // 要解构
    reactive_list_asyn_2.arr = res
    console.log('reactive_list_asyn_2: ', reactive_list_asyn_2)
  }, 2000)
}
</script>
<style scoped>
hr {
  margin: 10px 0;
}
</style>
